Passed
Pull Request — filestream (#173)
by
unknown
05:02
created

file-write.ts ➔ streamOriginalIntoNewFileAsync   A

Complexity

Conditions 3

Size

Total Lines 10
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 9
dl 0
loc 10
rs 9.95
c 0
b 0
f 0
cc 3
1
import {
2
    fsWritePromise,
3
    processFileSync,
4
    processFileAsync,
5
    fsExistsPromise,
6
    fsWriteFilePromise,
7
    fsRenamePromise,
8
    unlinkIfExistSync,
9
    unlinkIfExist,
10
    fsReadAsync,
11
    makeTempFilepath
12
} from "./util-file"
13
import * as fs from 'fs'
14
import { Id3TagRemover } from "./file-stream-processor"
15
import { WriteOptions } from "./types/write"
16
17
export function writeId3TagToFileSync(
18
    filepath: string,
19
    id3Tag: Buffer,
20
    options: WriteOptions
21
): void {
22
    if (!fs.existsSync(filepath)) {
23
        fs.writeFileSync(filepath, id3Tag)
24
        return
25
    }
26
    const tempFilepath = makeTempFilepath(filepath)
27
    processFileSync(filepath, 'r', (readFileDescriptor) => {
28
        try {
29
            processFileSync(tempFilepath, 'w', (writeFileDescriptor) => {
30
                fs.writeSync(writeFileDescriptor, id3Tag)
31
                copyFileWithoutId3TagSync(
32
                    readFileDescriptor,
33
                    writeFileDescriptor,
34
                    options.fileBufferSize
35
                )
36
            })
37
        } catch(error) {
38
            unlinkIfExistSync(tempFilepath)
39
            throw error
40
        }
41
    })
42
    fs.renameSync(tempFilepath, filepath)
43
}
44
45
export async function writeId3TagToFileAsync(
46
    filepath: string,
47
    id3Tag: Buffer,
48
    options: WriteOptions
49
): Promise<void> {
50
    if (!await fsExistsPromise(filepath)) {
51
        await fsWriteFilePromise(filepath, id3Tag)
52
        return
53
    }
54
    const tempFilepath = makeTempFilepath(filepath)
55
    await processFileAsync(filepath, 'r', async (readFileDescriptor) => {
56
        try {
57
            await processFileAsync(tempFilepath, 'w',
58
                async (writeFileDescriptor) => {
59
                    await fsWritePromise(writeFileDescriptor, id3Tag)
60
                    await copyFileWithoutId3TagAsync(
61
                        readFileDescriptor,
62
                        writeFileDescriptor,
63
                        options.fileBufferSize
64
                    )
65
                }
66
            )
67
        } catch(error) {
68
            await unlinkIfExist(tempFilepath)
69
            throw error
70
        }
71
72
    })
73
    await fsRenamePromise(tempFilepath, filepath)
74
}
75
76
function copyFileWithoutId3TagSync(
77
    readFileDescriptor: number,
78
    writeFileDescriptor: number,
79
    fileBufferSize?: number
80
) {
81
    const remover = new Id3TagRemover(fileBufferSize)
82
    do {
83
        const readBuffer = remover.getReadBuffer()
84
        const sizeRead = fs.readSync(readFileDescriptor, readBuffer)
85
        const { skipBuffer, writeBuffer } = remover.processReadBuffer(sizeRead)
86
        fs.readSync(readFileDescriptor, skipBuffer)
87
        fs.writeSync(writeFileDescriptor, writeBuffer)
88
    } while(remover.continue)
89
}
90
91
async function copyFileWithoutId3TagAsync(
92
    readFileDescriptor: number,
93
    writeFileDescriptor: number,
94
    fileBufferSize?: number
95
) {
96
    const remover = new Id3TagRemover(fileBufferSize)
97
    do {
98
        const readBuffer = remover.getReadBuffer()
99
        const sizeRead = await fsReadAsync(readFileDescriptor, readBuffer)
100
        const { skipBuffer, writeBuffer } = remover.processReadBuffer(sizeRead)
101
        await fsReadAsync(readFileDescriptor, skipBuffer)
102
        await fsWriteFilePromise(writeFileDescriptor, writeBuffer)
103
    } while(remover.continue)
104
}
105